//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#include <ddk.h>

class RegDevice : public CDeviceDriver
{
public:
    CARAPI Read(
        /* [in] */ Int64 u64Offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ EzByteBuf buffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Write(
        /* [in] */ Int64 u64Offset,
        /* [in] */ EzByteBuf buffer,
        /* [out] */ Int32 * pBytesWritten,
        /* [out] */ IEvent * * ppCompletionEvent);

    CARAPI Control(
        /* [in] */ Handle32 nControlCode,
        /* [in] */ EzByteBuf inBuffer,
        /* [out] */ EzByteBuf * pOutBuffer,
        /* [out] */ IEvent * * ppCompletionEvent);

    virtual void Dispose() {}
};

EXTERN IDeviceDriver * CDECL CreateRegDevice(uint_t uDeviceNo,
    void *pvParameter)
{
    RegDevice *pDriver = new RegDevice;
    if (NULL == pDriver) {
        kprintf("ERROR:There have no enough memory, %s, %d\n",
                        __FILE__, __LINE__);
        return NULL;
    }

    pDriver->AddRef();

    return pDriver;
}

ECode RegDevice::Read(
    /* [in] */ Int64 u64Offset,
    /* [in] */ Int32 bytesToRead,
    /* [out] */ EzByteBuf buffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode RegDevice::Write(
    /* [in] */ Int64 u64Offset,
    /* [in] */ EzByteBuf buffer,
    /* [out] */ Int32 * pBytesWritten,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode RegDevice::Control(
    /* [in] */ Handle32 nControlCode,
    /* [in] */ EzByteBuf inBuffer,
    /* [out] */ EzByteBuf * pOutBuffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    //Create different device for multiple threads
    if (nControlCode >= 1000) {
        return DzRegisterDevice(L"regdevice", nControlCode, NULL);
    }

    switch (nControlCode) {
    //use normally
        case 1:
            return DzRegisterDevice(L"ramdisk", 10, NULL);
    // DEVICENO_NONE
        case 2:
            return DzRegisterDevice(L"ramdisk", DEVICENO_NONE, NULL);
    // Having no driver for device
        case 3:
            return DzRegisterDevice(L"abcdefg", DEVICENO_NONE, NULL);
    // The length of device name is 31, and device has relevant driver
        case 4:
            return DzRegisterDevice(L"lengthofdevicename000000equal31",
                                            11, NULL);
    // The length of device name is 32, and device have no relevant driver
    // (Cannot config driver information in config.cpp)
        case 5:
            return DzRegisterDevice(L"abcdefghijklmnopqrstuvwxyz123456",
                                            DEVICENO_NONE, NULL);
    // Device has been registered statically in device table
        case 6:
            return DzRegisterDevice(L"lengthofdevicename000000equal31",
                            0, NULL);

            // Creating multiple threads in user mode, and call this method
        case 7:
            return DzRegisterDevice(L"regdevice", 100, NULL);

        default:
            return E_NOT_IMPLEMENTED;
    }
}
